package com.akjava.gwt.hangout.easyoverlay.client;
import java.util.ArrayList;
import java.util.List;
import com.akjava.gwt.html5.client.ColorPickWidget;
import com.akjava.gwt.html5.client.download.HTML5Download;
import com.akjava.gwt.html5.client.file.File;
import com.akjava.gwt.html5.client.file.FileUploadForm;
import com.akjava.gwt.html5.client.file.FileUtils;
import com.akjava.gwt.html5.client.file.FileUtils.DataURLListener;
import com.akjava.gwt.lib.client.StorageControler;
import com.akjava.gwt.lib.client.StorageDataList;
import com.akjava.gwt.lib.client.StorageDataList.HeaderAndValue;
import com.akjava.gwt.lib.client.StorageDataList.QuotaExceededError;
import com.akjava.gwt.lib.hangouts.client.Hangout;
import com.akjava.gwt.lib.hangouts.client.av.Av;
import com.akjava.gwt.lib.hangouts.client.av.effects.Effects;
import com.akjava.gwt.lib.hangouts.client.av.effects.ImageResource;
import com.akjava.gwt.lib.hangouts.client.av.effects.Overlay;
import com.akjava.gwt.lib.hangouts.client.av.effects.OverlayParameter;
import com.akjava.gwt.lib.hangoutsutils.client.SimpleGadget;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d.Composite;
import com.google.gwt.canvas.dom.client.Context2d.LineJoin;
import com.google.gwt.canvas.dom.client.Context2d.TextBaseline;
import com.google.gwt.dom.client.CanvasElement;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ContextMenuEvent;
import com.google.gwt.event.dom.client.ContextMenuHandler;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.gadgets.client.Gadget.AllowHtmlQuirksMode;
import com.google.gwt.gadgets.client.Gadget.ModulePrefs;
import com.google.gwt.gadgets.client.Gadget.UseLongManifestName;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
@ModulePrefs(title = "EasyOverlay")
@UseLongManifestName(false)
@AllowHtmlQuirksMode(false)
public class EasyOverlay extends SimpleGadget {
private ImageElement imgElement;
private Canvas canvas;
private Canvas originImage;
private Canvas overlayCanvas;
private XYPoint lastPoint;
private DataUriCommand currentCommand;
private long lastAvatorUpdate;
private StorageDataList storageList;
private int currentEditingId=-1;
private int penSize=32;
public static final int MODE_ERASE=0;
public static final int MODE_BLACK=1;
public static final int MODE_WHITE=2;
public static final int MODE_COLOR=3;
public static final int MODE_UNERASE=4;
private int penMode=MODE_ERASE;
private boolean mouseMoved;
@Override
protected void onApiReady() {
storageList=new StorageDataList(new StorageControler(), "imageData");
tab = new TabPanel();
final VerticalPanel editPanel=new VerticalPanel();
tab.add(editPanel,"Edit");
tab.selectTab(0);
HorizontalPanel top=new HorizontalPanel();
top.setWidth("100%");
top.setHorizontalAlignment(HorizontalPanel.ALIGN_RIGHT);
editPanel.add(top);
Button clearOverlay=new Button("Clear Overlay");
top.add(clearOverlay);
clearOverlay.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
clearOverlay();
}
});
//root.setStylePrimaryName("nomargin");
//root.setSpacing(0);
RootPanel.get().add(tab);
editPanel.setHorizontalAlignment(HorizontalPanel.ALIGN_CENTER);
//form
FileUploadForm upload=FileUtils.createSingleFileUploadForm(new DataURLListener() {
@Override
public void uploaded(File file, String value) {
try{
currentEditingId=-1;
setImage(value);
}catch(Exception e){
log("error-2:"+e.getMessage());
}
}
}, true);
editPanel.add(upload);
int cbase=18;
canvasWidth = cbase*16;
int ch=cbase*9;
zoomSize = 2;
/*
VerticalPanel bg=new VerticalPanel();
editPanel.add(bg);
bg.setSpacing(0);
*/
//size choose
HorizontalPanel sizes=new HorizontalPanel();
editPanel.add(sizes);
RadioButton smallS=new RadioButton("sizes");
smallS.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
penSize=16;
}
});
sizes.add(smallS);
sizes.add(new Label("small"));
RadioButton middleS=new RadioButton("sizes");
middleS.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
penSize=32;
}
});
middleS.setValue(true);
sizes.add(middleS);
sizes.add(new Label("middle"));
RadioButton largeS=new RadioButton("sizes");
largeS.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
penSize=48;
}
});
sizes.add(largeS);
sizes.add(new Label("large"));
//pen choose
HorizontalPanel pens=new HorizontalPanel();
editPanel.add(pens);
RadioButton eraseR=new RadioButton("pens");
pens.add(eraseR);
eraseR.setValue(true);
eraseR.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
penMode=MODE_ERASE;
}
});
pens.add(new Label("Erase"));
RadioButton uneraseR=new RadioButton("pens");
uneraseR.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
penMode=MODE_UNERASE;
}
});
pens.add(uneraseR);
pens.add(new Label("UnErase"));
RadioButton blackR=new RadioButton("pens");
pens.add(blackR);
pens.add(new Label("Black"));
blackR.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
penMode=MODE_BLACK;
}
});
RadioButton whiteR=new RadioButton("pens");
pens.add(whiteR);
pens.add(new Label("White"));
whiteR.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
penMode=MODE_WHITE;
}
});
RadioButton customR=new RadioButton("pens");
pens.add(customR);
pens.add(new Label("Color"));
customR.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
penMode=MODE_COLOR;
}
});
colorPicker = new ColorPickWidget();
colorPicker.setValue(0xff0000);
editPanel.add(colorPicker);
canvas = Canvas.createIfSupported();
canvas.setStylePrimaryName("transparent_bg");//or bg
canvas.setSize(canvasWidth+"px", ch+"px");
//canvas.setSize("272px", "153px");
canvas.setCoordinateSpaceWidth(canvasWidth*zoomSize);
canvas.setCoordinateSpaceHeight(ch*zoomSize);
editPanel.add(canvas);
overlayCanvas=Canvas.createIfSupported();
overlayCanvas.setCoordinateSpaceWidth(canvasWidth*zoomSize);
overlayCanvas.setCoordinateSpaceHeight(ch*zoomSize);
originImage=Canvas.createIfSupported();
originImage.setCoordinateSpaceWidth(canvasWidth*zoomSize);
originImage.setCoordinateSpaceHeight(ch*zoomSize);
canvas.addMouseMoveHandler(new MouseMoveHandler() {
@Override
public void onMouseMove(MouseMoveEvent event) {
if(editBt.isVisible()){
return;
}
if(mouseDown){
mouseMoved=true;
int x=event.getX()*zoomSize;
int y=event.getY()*zoomSize;
XYPoint newPoint=new XYPoint(x,y);
switch(penMode){
case MODE_ERASE:
erase(lastPoint,newPoint);
break;
case MODE_UNERASE:
unerase(lastPoint,newPoint);
break;
case MODE_BLACK:
drawLine(lastPoint,newPoint,"#000");
break;
case MODE_WHITE:
drawLine(lastPoint,newPoint,"#fff");
break;
case MODE_COLOR:
drawLine(lastPoint,newPoint,colorPicker.getValueAsHex());
break;
}
lastPoint=newPoint;
long c=System.currentTimeMillis();
if(lastAvatorUpdate+200<c){
lastAvatorUpdate=c;
updateAvator();
}
}
}
});
canvas.addMouseDownHandler(new MouseDownHandler() {
@Override
public void onMouseDown(MouseDownEvent event) {
if(editBt.isVisible()){
return;
}
mouseRight=event.getNativeButton()==NativeEvent.BUTTON_RIGHT;
mouseDown=true;
lastPoint=mouseToXYPoint(event.getX(),event.getY());
currentCommand=new DataUriCommand();
currentCommand.setBeforeUri(canvas.toDataUrl("image/png"));
}
});
canvas.addMouseUpHandler(new MouseUpHandler() {
@Override
public void onMouseUp(MouseUpEvent event) {
if(editBt.isVisible()){
return;
}
if(!mouseMoved){
XYPoint dummyPt=new XYPoint(lastPoint.getX()+1, lastPoint.getY()+1);
switch(penMode){
case MODE_ERASE:
erase(lastPoint,dummyPt);
break;
case MODE_UNERASE:
unerase(lastPoint,dummyPt);
break;
case MODE_BLACK:
drawLine(lastPoint,dummyPt,"#000");
break;
case MODE_WHITE:
drawLine(lastPoint,dummyPt,"#fff");
break;
case MODE_COLOR:
drawLine(lastPoint,dummyPt,colorPicker.getValueAsHex());
break;
}
}
mouseMoved=false;
mouseDown=false;
lastPoint=null;
updateAvator();
currentCommand.setAfterUri(canvas.toDataUrl("image/png"));
undoBt.setEnabled(true);
}
});
//stop context menu;
canvas.addDomHandler(new ContextMenuHandler() {
@Override
public void onContextMenu(ContextMenuEvent event) {
event.stopPropagation();
event.preventDefault();
}
}, ContextMenuEvent.getType());
Button download=new Button("Download");
download.addClickHandler(new ClickHandler() {
private Anchor downloadAnchor;
@Override
public void onClick(ClickEvent event) {
//Window.open(canvas.toDataUrl("image/png"), "easyoverlay"+dindex, null);
//Firefox Fine.Chrome so but.
//ExportUtils.openTabAbsoluteURLImage(canvas.toDataUrl("image/png"), "easyoverlay"+dindex);
copyToOverlayCanvas(canvas.getCanvasElement());
if(downloadAnchor!=null){
downloadAnchor.removeFromParent();
}
downloadAnchor = HTML5Download.generateBase64DownloadLink(overlayCanvas.toDataUrl("image/png"),"image/png","holeInBlank"+currentEditingId,"click to download",true);
editPanel.add(downloadAnchor);
dindex++;
}
});
Button stock=new Button("Copy to Stock");
stock.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
//Window.open(canvas.toDataUrl("image/png"), "easyoverlay"+dindex, null);
//Firefox Fine.Chrome so but.
//ExportUtils.openTabAbsoluteURLImage(canvas.toDataUrl("image/png"), "easyoverlay"+dindex);
copyToOverlayCanvas(canvas.getCanvasElement());
String url=overlayCanvas.toDataUrl("image/png");
try{
if(currentEditingId==-1){
int id=storageList.addData("", url);
ImageItem item=new ImageItem(id,url);
imageItems.add(item);
log("id:"+id+","+storageList.getDataValue(id).getData().substring(0,10));
}else{
storageList.updateDataValue(currentEditingId, url);
ImageItem item=getItem(currentEditingId);
item.setDataUri(url);
}
updateList();
tab.selectTab(1);
}catch(QuotaExceededError e){
Window.alert("Limit Over.to store delate old stock image");
log(e.getMessage());
}
}
});
HorizontalPanel exbuttons=new HorizontalPanel();
HorizontalPanel buttons=new HorizontalPanel();
editPanel.add(buttons);
editPanel.add(exbuttons);
exbuttons.add(download);
exbuttons.add(stock);
overlayBt = new Button("Overlay");
overlayBt.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
setOverlay(canvas.getCanvasElement());
}
});
buttons.add(overlayBt);
editBt = new Button("Edit");
editBt.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if(overlay!=null){
overlay.setVisible(false);
updateAvator();
overlayBt.setVisible(true);
editBt.setVisible(false);
reset.setEnabled(true);
}
}
});
editBt.setVisible(false);
buttons.add(editBt);
undoBt = new Button("Undo");
undoBt.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
currentCommand.undo();
undoBt.setEnabled(false);
redoBt.setEnabled(true);
}
});
buttons.add(undoBt);
undoBt.setEnabled(false);
redoBt = new Button("Redo");
redoBt.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
currentCommand.redo();
undoBt.setEnabled(true);
redoBt.setEnabled(false);
}
});
redoBt.setEnabled(false);
buttons.add(redoBt);
reset = new Button("Reset");
reset.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
currentCommand=new DataUriCommand();
currentCommand.setBeforeUri(canvas.toDataUrl("image/png"));
canvas.getContext2d().save();
canvas.getContext2d().setGlobalCompositeOperation(Composite.COPY);
canvas.getContext2d().translate(originImage.getCoordinateSpaceWidth(), 0); //flip horizontal
canvas.getContext2d().scale(-1, 1);
canvas.getContext2d().drawImage(originImage.getCanvasElement(), 0, 0);
canvas.getContext2d().restore();
currentCommand.setAfterUri(canvas.toDataUrl("image/png"));
updateAvator();
undoBt.setEnabled(true);
redoBt.setEnabled(false);
}
});
buttons.add(reset);
final VerticalPanel listPanel=new VerticalPanel();
tab.add(listPanel,"Stocks");
//controler,fist,pre,next,auto-play + time,clear
/*
FileUploadForm uploadFiles=FileUtils.createMultiFileUploadForm(new DataURLsListener() {
@Override
public void uploaded(final List<File> files, final List<String> values) {
log("uploaded:"+values.size());
String url=values.remove(0);
final ImageElementLoader loader=new ImageElementLoader();
final ImageElementListener listener= new ImageElementListener() {
@Override
public void onLoad(ImageElement element) {
overlayCanvas.getContext2d().save();
clearCanvas(overlayCanvas);
overlayCanvas.getContext2d().restore();
overlayCanvas.getContext2d().save();
drawFitCenter(overlayCanvas, element);
overlayCanvas.getContext2d().restore();
String resizedImage=overlayCanvas.toDataUrl("image/png");//origin
ImageItem item=new ImageItem(resizedImage);
container.add(item);
if(values.size()>0){
String url=values.remove(0);
loader.load(url, this);
}
}
};
loader.load(url,listener);
}
}, true);
listPanel.add(uploadFiles);
*/
container=new VerticalPanel();
//container.setWidth((canvasWidth-20)+"px");
ScrollPanel scroll=new ScrollPanel();
scroll.setHeight("330px");
scroll.setWidth((canvasWidth)+"px");
listPanel.add(scroll);
scroll.setWidget(container);
List<HeaderAndValue> hvs=storageList.getDataList();
for(HeaderAndValue hv:hvs){
ImageItem item=new ImageItem(hv.getId(), hv.getData());
imageItems.add(item);
}
updateList();
}
private void clearOverlay(){
if(overlay!=null){
overlay.setVisible(false);
}
}
private void setImage(String url){
new ImageElementLoader().load(url, new ImageElementListener() {
@Override
public void onLoad(ImageElement element) {
imgElement=element;
log("size:"+imgElement.getWidth()+"x"+imgElement.getHeight());
clearOverlay();
drawImage(imgElement);
updateAvator();
overlayBt.setVisible(true);
editBt.setVisible(false);
reset.setEnabled(true);
}
});
}
private ImageItem getItem(int id){
for(ImageItem item:imageItems){
if(item.getId()==id){
return item;
}
}
return null;
}
protected void updateList() {
container.clear();
for(ImageItem item:imageItems){
container.add(item);
}
//TODO select border;
}
private void drawText(String text){
overlayCanvas.getContext2d().save();
overlayCanvas.getContext2d().setFont("30px Arial");
overlayCanvas.getContext2d().setShadowColor("Black");
overlayCanvas.getContext2d().setFillStyle("white");
overlayCanvas.getContext2d().setShadowOffsetX(2);
overlayCanvas.getContext2d().setShadowOffsetY(2);
double w=overlayCanvas.getContext2d().measureText(text).getWidth();
//originImage.getContext2d().setTextBaseline(TextBaseline.ALPHABETIC);
int halfHeight=30;
overlayCanvas.getContext2d().fillText(text, (overlayCanvas.getCoordinateSpaceWidth()-w)/2, halfHeight);
//originImage.getContext2d().get
overlayCanvas.getContext2d().restore();
}
private List<ImageItem> imageItems=new ArrayList<ImageItem>();
/*
private void clearCanvas(Canvas targetCanvas){
targetCanvas.getContext2d().setFillStyle("rgba(0,0,0,0)");
targetCanvas.getContext2d().setGlobalCompositeOperation(Composite.COPY);
targetCanvas.getContext2d().fillRect(0, 0, overlayCanvas.getCoordinateSpaceWidth(), overlayCanvas.getCoordinateSpaceHeight());
}*/
private void setOverlay(ImageElement element,boolean flip){
if(overlay!=null){
overlay.setVisible(false);
}
copyToOverlayCanvas(element,flip);
String url=overlayCanvas.toDataUrl("image/png");
ImageResource resource=Effects.creatImageResource(url);
overlay = resource.showOverlay(OverlayParameter.create().scale(1, Effects.ScaleReference.WIDTH));
Av.clearAvatar(Hangout.getParticipantId());
overlayBt.setVisible(false);
editBt.setVisible(true);
undoBt.setEnabled(false);
redoBt.setEnabled(false);
}
private void setOverlay(CanvasElement element){
if(overlay!=null){
overlay.setVisible(false);
}
copyToOverlayCanvas(element);
String url=overlayCanvas.toDataUrl("image/png");
ImageResource resource=Effects.creatImageResource(url);
overlay = resource.showOverlay(OverlayParameter.create().scale(1, Effects.ScaleReference.WIDTH));
Av.clearAvatar(Hangout.getParticipantId());
overlayBt.setVisible(false);
editBt.setVisible(true);
undoBt.setEnabled(false);
redoBt.setEnabled(false);
reset.setEnabled(false);
}
private VerticalPanel container;
//original
public class ImageItem extends HorizontalPanel{
private String dataUri;
public String getDataUri() {
return dataUri;
}
public void setDataUri(String dataUri) {
this.dataUri = dataUri;
img.setUrl(dataUri);
}
private int id;
private Image img;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public ImageItem(int idValue,String src){
this.id=idValue;
this.dataUri=src;
this.setStylePrimaryName("marginbotton");
VerticalPanel main=new VerticalPanel();
add(main);
img = new Image(src);
img.setStylePrimaryName("transparent_bg");
img.setWidth((canvasWidth-20)+"px");
main.add(img);
HorizontalPanel controler=new HorizontalPanel();
controler.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);
controler.setSpacing(0);
main.add(controler);
Button show=new Button("Overlay");
show.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
ImageElementLoader loader=new ImageElementLoader();
loader.load(dataUri, new ImageElementListener() {
@Override
public void onLoad(ImageElement element) {
setOverlay(element,false);
//TODO setBorder;
}
});
}
});
controler.add(show);
Button edit=new Button("Edit");
edit.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
clearOverlay();
currentEditingId=id;
setImage(dataUri);
tab.selectTab(0);
}
});
controler.add(edit);
Button remove=new Button("Remove");
remove.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
boolean ret=Window.confirm("remove #"+id+" image");
if(ret){
storageList.clearData(id);
imageItems.remove(ImageItem.this);
updateList();
}
}
});
controler.add(remove);
controler.add(new Label("#"+idValue));
}
}
private void copyToOverlayCanvas(ImageElement element,boolean flip){
//flip horizontal
overlayCanvas.getContext2d().save();
overlayCanvas.getContext2d().setGlobalCompositeOperation(Composite.COPY);
if(flip){
overlayCanvas.getContext2d().translate(canvas.getCoordinateSpaceWidth(), 0); //flip horizontal
overlayCanvas.getContext2d().scale(-1, 1);
}
overlayCanvas.getContext2d().drawImage(element, 0, 0);
overlayCanvas.getContext2d().restore();
}
private void copyToOverlayCanvas(CanvasElement element){
//flip horizontal
overlayCanvas.getContext2d().save();
overlayCanvas.getContext2d().setGlobalCompositeOperation(Composite.COPY);
overlayCanvas.getContext2d().translate(canvas.getCoordinateSpaceWidth(), 0); //flip horizontal
overlayCanvas.getContext2d().scale(-1, 1);
overlayCanvas.getContext2d().drawImage(element, 0, 0);
overlayCanvas.getContext2d().restore();
}
private int dindex;
private Overlay overlay;
private XYPoint mouseToXYPoint(int mx,int my){
int x=mx*zoomSize;
int y=my*zoomSize;
XYPoint newPoint=new XYPoint(x,y);
return newPoint;
}
private void erase(XYPoint p1,XYPoint p2){
canvas.getContext2d().save();
canvas.getContext2d().setLineWidth(penSize);
canvas.getContext2d().setLineJoin(LineJoin.ROUND);
canvas.getContext2d().setStrokeStyle("#000");
canvas.getContext2d().setGlobalCompositeOperation("destination-out");
canvas.getContext2d().beginPath();
canvas.getContext2d().moveTo(p1.getX(),p1.getY());
canvas.getContext2d().lineTo(p2.getX(),p2.getY());
canvas.getContext2d().closePath();
canvas.getContext2d().stroke();
canvas.getContext2d().restore();
}
private void unerase(XYPoint p1,XYPoint p2){
overlayCanvas.getContext2d().clearRect(0, 0, overlayCanvas.getCoordinateSpaceWidth(), overlayCanvas.getCoordinateSpaceHeight());
overlayCanvas.getContext2d().save();
overlayCanvas.getContext2d().setLineWidth(penSize+2);
overlayCanvas.getContext2d().setLineJoin(LineJoin.ROUND);
overlayCanvas.getContext2d().setStrokeStyle("#000");
overlayCanvas.getContext2d().setGlobalCompositeOperation(Composite.SOURCE_OVER);
overlayCanvas.getContext2d().beginPath();
overlayCanvas.getContext2d().moveTo(p1.getX(),p1.getY());
overlayCanvas.getContext2d().lineTo(p2.getX(),p2.getY());
overlayCanvas.getContext2d().closePath();
overlayCanvas.getContext2d().stroke();
//TODO clip
overlayCanvas.getContext2d().setGlobalCompositeOperation(Composite.SOURCE_IN);
overlayCanvas.getContext2d().translate(originImage.getCoordinateSpaceWidth(), 0); //flip horizontal
overlayCanvas.getContext2d().scale(-1, 1);
overlayCanvas.getContext2d().drawImage(originImage.getCanvasElement(), 0, 0);
overlayCanvas.getContext2d().restore();
canvas.getContext2d().save();
canvas.getContext2d().drawImage(overlayCanvas.getCanvasElement(), 0, 0);
canvas.getContext2d().restore();
}
private void drawLine(XYPoint p1,XYPoint p2,String color){
canvas.getContext2d().save();
canvas.getContext2d().setLineWidth(penSize);
canvas.getContext2d().setLineJoin(LineJoin.ROUND);
canvas.getContext2d().setStrokeStyle(color);
canvas.getContext2d().setGlobalCompositeOperation(Composite.SOURCE_OVER);
canvas.getContext2d().beginPath();
canvas.getContext2d().moveTo(p1.getX(),p1.getY());
canvas.getContext2d().lineTo(p2.getX(),p2.getY());
canvas.getContext2d().closePath();
canvas.getContext2d().stroke();
canvas.getContext2d().restore();
}
public class XYPoint{
public XYPoint(int x,int y){
this.x=x;
this.y=y;
}
private int x;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
private int y;
}
boolean mouseDown;
boolean mouseRight;
private int zoomSize;
private Button editBt;
private Button overlayBt;
private Button undoBt;
private Button redoBt;
private TabPanel tab;
private int canvasWidth;
private Button reset;
private ColorPickWidget colorPicker;
protected void drawImage(ImageElement img) {
try{
//should I clear?
//clearCanvas(originImage);
originImage.getContext2d().clearRect(0, 0, originImage.getCoordinateSpaceWidth(), originImage.getCoordinateSpaceHeight());
//drawCenter(canvas,img);
drawFitCenter(originImage,img);
canvas.getContext2d().clearRect(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
canvas.getContext2d().save();
canvas.getContext2d().translate(originImage.getCoordinateSpaceWidth(), 0); //flip horizontal
canvas.getContext2d().scale(-1, 1);
//canvas.getContext2d().transform(-1, 0, 0, 1, 0, 0);
canvas.getContext2d().drawImage(originImage.getCanvasElement(), 0, 0);
canvas.getContext2d().restore();
}catch(Exception e){
log("error:"+e.getMessage());
}
//canvas.getContext2d().setFillStyle("rgba(0,0,0,0)");
//canvas.getContext2d().setGlobalCompositeOperation("destination-out");
//canvas.getContext2d().fillRect(100, 100, 100, 100);
}
//simple draw center
private static void drawFitCenter(Canvas canvas,ImageElement img){
int cw=canvas.getCoordinateSpaceWidth();
int ch=canvas.getCoordinateSpaceHeight();
int iw=img.getWidth();
int ih=img.getHeight();
double rw=(double)cw/iw;
double rh=(double)ch/ih;
double niw,nih;
if(rw<rh){
niw=cw;
nih=rw*ih;
}else{
nih=ch;
niw=rh*iw;
}
double dx=(cw-niw)/2;
double dy=(ch-nih)/2;
log("draw:"+dx+","+dy);
canvas.getContext2d().drawImage(img, dx, dy, niw, nih);
}
//simple draw center
private static void drawCenter(Canvas canvas,ImageElement img){
int cw=canvas.getCoordinateSpaceWidth();
int ch=canvas.getCoordinateSpaceHeight();
int dx=(cw-img.getWidth())/2;
int dy=(ch-img.getHeight())/2;
log("draw:"+dx+","+dy);
canvas.getContext2d().drawImage(img, dx, dy, img.getWidth(), img.getHeight());
}
private void updateAvator(){
overlayCanvas.getContext2d().save();
overlayCanvas.getContext2d().setGlobalCompositeOperation(Composite.COPY);
overlayCanvas.getContext2d().drawImage(canvas.getCanvasElement(), 0,0);
overlayCanvas.getContext2d().restore();
drawText("Edit Mode,this is preview image");
String url=overlayCanvas.toDataUrl();
/*
Canvas tmp=Canvas.createIfSupported();
int dw=canvas.getCoordinateSpaceWidth()/30;
int dh=canvas.getCoordinateSpaceHeight()/30;
tmp.setCoordinateSpaceWidth(dw);
tmp.setCoordinateSpaceHeight(dh);
tmp.getContext2d().drawImage(canvas.getCanvasElement(), 0, 0,dw,dh);
url=tmp.toDataUrl("image/png");
log("avator-length:"+url.length());
log(url);
*/
Av.setAvatar(Hangout.getParticipantId(),url );
}
public class ImageElementLoader{
public void load(String url,final ImageElementListener listener){
final Image img=new Image(url);
img.setVisible(false);
img.addLoadHandler(new LoadHandler() {
@Override
public void onLoad(LoadEvent event) {
RootPanel.get().remove(img);
ImageElement element=ImageElement.as(img.getElement());
listener.onLoad(element);
}
});
RootPanel.get().add(img);
}
}
public static ImageElement dataUriToImageElement(String dataUri){
return ImageElement.as(new Image(dataUri).getElement());
}
public interface ImageElementListener{
public void onLoad(ImageElement element);
}
public class DataUriCommand implements Command{
private String beforeUri;
private String afterUri;
public String getBeforeUri() {
return beforeUri;
}
public void setBeforeUri(String beforeUri) {
this.beforeUri = beforeUri;
}
public String getAfterUri() {
return afterUri;
}
public void setAfterUri(String afterUri) {
this.afterUri = afterUri;
}
@Override
public void undo() {
ImageElementLoader loader=new ImageElementLoader();
loader.load(beforeUri, new ImageElementListener() {
@Override
public void onLoad(ImageElement element) {
canvas.getContext2d().save();
canvas.getContext2d().setGlobalCompositeOperation(Composite.COPY);
canvas.getContext2d().drawImage(element,0,0);
canvas.getContext2d().restore();
updateAvator();
}
});
}
@Override
public void redo() {
ImageElementLoader loader=new ImageElementLoader();
loader.load(afterUri, new ImageElementListener() {
@Override
public void onLoad(ImageElement element) {
canvas.getContext2d().save();
canvas.getContext2d().setGlobalCompositeOperation(Composite.COPY);
canvas.getContext2d().drawImage(element,0,0);
canvas.getContext2d().restore();
updateAvator();
}
});
}
}
/**
* this faild some edge showd,i need stop antialiase.
* @author aki
*
*/
public class EraseCommand implements Command{
List<XYPoint> positions=new ArrayList<XYPoint>();
public void add(XYPoint point){
positions.add(point);
}
public int size(){
return positions.size();
}
@Override
public void undo() {
if(size()==1){//click only
unerase(positions.get(0), positions.get(0));
}
for(int i=0;i<positions.size()-1;i++){
unerase(positions.get(i), positions.get(i+1));
}
updateAvator();
}
@Override
public void redo() {
if(size()==1){//click only
erase(positions.get(0), positions.get(0));
}
for(int i=0;i<positions.size()-1;i++){
erase(positions.get(i), positions.get(i+1));
}
updateAvator();
}
}
}